﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using StockLib;
using StockUtil;

namespace StockControl
{
    public partial class StockKGraphControl : Control
    {
        private bool _showAxis = false;
        private bool _showCursor = false;

        private bool ShowAxis
        {
            get { return this._showAxis; }
            set { this._showAxis = value; }
        }
        private bool ShowCursor
        {
            get { return this._showCursor; }
            set { this._showCursor = value; }
        }

        Bitmap bitmapOldXAxis = null;
        Bitmap bitmapNewXAxis = null;
        Point locationLastXAxis = Point.Empty;
        Bitmap bitmapOldYAxis = null;
        Bitmap bitmapNewYAxis = null;
        Point locationLastYAxis = Point.Empty;
        Bitmap bitmapOldXCursor = null;
        Bitmap bitmapNewXCursor = null;
        Point locationLastXCursor = Point.Empty;
        Bitmap bitmapOldYCursor = null;
        Bitmap bitmapNewYCursor = null;
        Point locationLastYCursor = Point.Empty;

        private void StockGraphControl_MouseMove(object sender, MouseEventArgs e)
        {
            ChangeGraphTitle(e.Location);

            MoveCursor(e.Location);
        }

        private void ChangeGraphTitle(Point location)
        {
            int index = GetXIndex(location.X);
        }

        private void MoveCursor(Point location)
        {
            if (!ShowAxis && !ShowCursor)
                return;

            if (!this.Focused)
                return;

            //计算X轴坐标指示器矩形
            Rectangle rectBitmapXAxis = new Rectangle();
            rectBitmapXAxis.X = location.X;
            rectBitmapXAxis.Y = rectXAxis.Top + 1;
            rectBitmapXAxis.Height = rectXAxis.Height - 1;
            rectBitmapXAxis.Width = (int)(TextRenderer.MeasureText("2009/12/23", Font).Width * 1.1f);
            if (location.X + rectBitmapXAxis.Width > rectGraph.Right)
            {
                rectBitmapXAxis.X = rectGraph.Right - rectBitmapXAxis.Width;
            }

            //计算Y轴坐标指示器矩形
            Rectangle rectBitmapYAxis = new Rectangle();
            rectBitmapYAxis.X = rectYAxis.Left + 1;
            rectBitmapYAxis.Height = (int)(TextRenderer.MeasureText("2009/12/23", Font).Height * 1.5f);
            rectBitmapYAxis.Width = rectYAxis.Width - 1;
            rectBitmapYAxis.Y = location.Y - rectBitmapYAxis.Height + 1;

            //计算X轴十字光标矩形
            Rectangle rectBitmapXCursor = new Rectangle();
            rectBitmapXCursor.X = location.X;
            rectBitmapXCursor.Y = rectGraph.Top;
            rectBitmapXCursor.Height = rectGraph.Height;
            rectBitmapXCursor.Width = 1;

            //计算Y轴十字光标矩形
            Rectangle rectBitmapYCursor = new Rectangle();
            rectBitmapYCursor.X = rectGraph.Left;
            rectBitmapYCursor.Y = location.Y;
            rectBitmapYCursor.Height = 1;
            rectBitmapYCursor.Width = rectGraph.Width;

            using (Graphics g = CreateGraphics())
            {
                if (bitmapNewXAxis == null && bitmapNewYAxis == null && bitmapNewXCursor == null && bitmapNewYCursor == null)
                {
                    bitmapOldXAxis = new Bitmap(rectBitmapXAxis.Width, rectBitmapXAxis.Height, g);
                    bitmapNewXAxis = new Bitmap(rectBitmapXAxis.Width, rectBitmapXAxis.Height, g);
                    bitmapOldYAxis = new Bitmap(rectBitmapYAxis.Width, rectBitmapYAxis.Height, g);
                    bitmapNewYAxis = new Bitmap(rectBitmapYAxis.Width, rectBitmapYAxis.Height, g);
                    bitmapOldXCursor = new Bitmap(rectBitmapXCursor.Width, rectBitmapXCursor.Height, g);
                    bitmapNewXCursor = new Bitmap(rectBitmapXCursor.Width, rectBitmapXCursor.Height, g);
                    bitmapOldYCursor = new Bitmap(rectBitmapYCursor.Width, rectBitmapYCursor.Height, g);
                    bitmapNewYCursor = new Bitmap(rectBitmapYCursor.Width, rectBitmapYCursor.Height, g);
                }
                else
                {
                    // 在原位置恢复位图
                    g.DrawImage(bitmapOldXAxis, locationLastXAxis);
                    g.DrawImage(bitmapOldYAxis, locationLastYAxis);
                    g.DrawImage(bitmapOldXCursor, locationLastXCursor);
                    g.DrawImage(bitmapOldYCursor, locationLastYCursor);
                }

                // 在新位置保存位图
                using (Graphics bmg = Graphics.FromImage(bitmapOldXAxis))
                {
                    bmg.CopyFromScreen(PointToScreen(rectBitmapXAxis.Location), Point.Empty, bitmapOldXAxis.Size);
                }
                using (Graphics bmg = Graphics.FromImage(bitmapOldYAxis))
                {
                    bmg.CopyFromScreen(PointToScreen(rectBitmapYAxis.Location), Point.Empty, bitmapOldYAxis.Size);
                }

                if (ShowCursor)
                {
                    using (Graphics bmg = Graphics.FromImage(bitmapOldXCursor))
                    {
                        bmg.CopyFromScreen(PointToScreen(rectBitmapXCursor.Location), Point.Empty, bitmapOldXCursor.Size);
                    }
                    using (Graphics bmg = Graphics.FromImage(bitmapOldYCursor))
                    {
                        bmg.CopyFromScreen(PointToScreen(rectBitmapYCursor.Location), Point.Empty, bitmapOldYCursor.Size);
                    }
                }

                // 绘新位置绘制
                using (Graphics bmg = Graphics.FromImage(bitmapNewXAxis))
                {
                    string textXAxis = string.Empty;
                    int index = GetXIndex(location.X);
                    if (index >= indexStart && index <= indexEnd)
                    {
                        DateTime dateX = DateTimeHelper.FromGTime(KData[index].Time);
                        textXAxis = dateX.ToString(@"yyyy\/MM\/dd");
                    }
                    if (!string.IsNullOrEmpty(textXAxis))
                    {
                        Rectangle rect = new Rectangle(0, 0, rectBitmapXAxis.Width, rectBitmapXAxis.Height);
                        bmg.FillRectangle(Brushes.DarkBlue, rect);
                        bmg.DrawLine(StockProfile.Pens.AxisLinePen, rect.Left, rect.Top, rect.Left, rect.Bottom);
                        bmg.DrawLine(StockProfile.Pens.AxisLinePen, rect.Right - 1, 0, rect.Right - 1, rect.Bottom);
                        TextRenderer.DrawText(bmg, textXAxis, Font, rect, Color.White, TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter);
                        g.DrawImage(bitmapNewXAxis, rectBitmapXAxis.Location);
                    }
                }

                using (Graphics bmg = Graphics.FromImage(bitmapNewYAxis))
                {
                    string textYAxis = string.Empty;
                    if (kIndicator.rectGraph.Contains(location))
                    {
                        float yValue = kIndicator.GetYValue(location.Y);
                        //if (yValue >= kIndicator.valueMin && yValue <= kIndicator.valueMax)
                        if (location.Y > kIndicator.rectGraph.Top && location.Y < kIndicator.rectGraph.Bottom)
                        {
                            textYAxis = string.Format("{0:#0.00}", yValue);
                        }
                    }
                    else
                    {
                        foreach (StockIndicator indicator in otherIndicators)
                        {
                            if (indicator.rectGraph.Contains(location))
                            {
                                float yValue = indicator.GetYValue(location.Y);
                                //if (yValue >= indicator.valueMin && yValue <= indicator.valueMax)
                                if (location.Y > indicator.rectGraph.Top && location.Y < indicator.rectGraph.Bottom)
                                {
                                    textYAxis = string.Format("{0:#0.00}", yValue);
                                }
                                break;
                            }
                        }
                    }

                    if (!string.IsNullOrEmpty(textYAxis))
                    {
                        Rectangle rect = new Rectangle(0, 0, rectBitmapYAxis.Width, rectBitmapYAxis.Height);
                        bmg.FillRectangle(Brushes.DarkBlue, rect);
                        bmg.DrawLine(StockProfile.Pens.AxisLinePen, rect.Left, rect.Top, rect.Right, rect.Top);
                        bmg.DrawLine(StockProfile.Pens.AxisLinePen, rect.Left, rect.Bottom - 1, rect.Right, rect.Bottom - 1);
                        TextRenderer.DrawText(bmg, textYAxis, Font, rect, Color.White, TextFormatFlags.VerticalCenter | TextFormatFlags.Left);
                        g.DrawImage(bitmapNewYAxis, rectBitmapYAxis.Location);
                    }
                }

                if (ShowCursor)
                {
                    if (location.X < rectGraph.Right && location.X > rectGraph.Left && location.Y < rectGraph.Bottom && location.Y > rectGraph.Top)
                    {
                        using (Graphics bmg = Graphics.FromImage(bitmapNewXCursor))
                        {
                            Rectangle rect = new Rectangle(0, 0, bitmapNewXCursor.Width, bitmapNewXCursor.Height);
                            bmg.DrawLine(Pens.Gray, rect.Left, rect.Top, rect.Left, rect.Bottom);
                            g.DrawImage(bitmapNewXCursor, rectBitmapXCursor.Location);
                        }

                        using (Graphics bmg = Graphics.FromImage(bitmapNewYCursor))
                        {
                            Rectangle rect = new Rectangle(0, 0, bitmapNewYCursor.Width, bitmapNewYCursor.Height);
                            bmg.DrawLine(Pens.Gray, rect.Left, rect.Top, rect.Right, rect.Top);
                            g.DrawImage(bitmapNewYCursor, rectBitmapYCursor.Location);
                        }
                    }
                }

                locationLastXAxis = rectBitmapXAxis.Location;
                locationLastYAxis = rectBitmapYAxis.Location;

                if (ShowCursor)
                {
                    locationLastXCursor = rectBitmapXCursor.Location;
                    locationLastYCursor = rectBitmapYCursor.Location;
                }
            }
        }

        private void StockGraphControl_DoubleClick(object sender, EventArgs e)
        {
            ShowCursor = !ShowCursor;
        }

        private void StockGraphControl_Leave(object sender, EventArgs e)
        {
            if (this.FindForm().ContainsFocus)
            {
                this.Focus();
            }
            else
            {
                Release();
            }
        }

        private void Release()
        {
            ShowCursor = false;
            ShowAxis = false;

            if (bitmapNewXAxis != null && bitmapNewYAxis != null && bitmapNewXCursor != null && bitmapNewYCursor != null)
            {
                bitmapOldXAxis.Dispose();
                bitmapOldXAxis = null;
                bitmapNewXAxis.Dispose();
                bitmapNewXAxis = null;

                bitmapOldYAxis.Dispose();
                bitmapOldYAxis = null;
                bitmapNewYAxis.Dispose();
                bitmapNewYAxis = null;

                bitmapOldXCursor.Dispose();
                bitmapOldXCursor = null;
                bitmapNewXCursor.Dispose();
                bitmapNewXCursor = null;

                bitmapOldYCursor.Dispose();
                bitmapOldYCursor = null;
                bitmapNewYCursor.Dispose();
                bitmapNewYCursor = null;
            }
        }
    }
}
